/**
 * 
 */
package it.unical.canonaco.rende.igpe.game.cbv.guilayer.gamemanagermenu.menucomponent;

import it.unical.canonaco.rende.igpe.game.cbv.guilayer.AnimatedPanel;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.GUIGenericPawn;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.ImageProvider;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.OverallGUILayoutFactory;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.gamemanagermenu.GameManagerMenu;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.guievents.GraphicEventManager;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.match.MatchPanel;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.SpriteSheetCache;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.SpriteSheetInterface;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.sprites.key.AbstractSheetKey;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.GameManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.MatchManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.ActionCoordinateInfo;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.AddCharacterInfo;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.StartingPointAction;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.ai.AutomatedPlayerController;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.ai.decisiontreeai.DecisionTreeAI;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.filehandlers.IniLoader;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Character;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.BattlePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.SimplePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Chessboard;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.MapManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.EventListener;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.EventManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.GenericEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.NotEnoughtCharacterEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.OutOfMaxCharacterEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.StartingPositionEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.exceptions.InvalidFileException;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.omg.CORBA.OBJ_ADAPTER;

/**
 * @author Massimo Canonaco
 *
 */
public class PrePlayMatchPanel extends AnimatedPanel implements EventListener//JPanel 
{
	static public final String PRE_PLAY_MATCH_PANEL_NAME = "prePlayMatchPanel";
	static private final String SETTINGS_FILE = "cbvapps"+File.separator+"uiresource"+File.separator+"matchschema.ini";
	
	/** */
	private MapAreaZone016 mapMenu;
	
	/** */
	private GameManagerMenu monitor;
	
	/** */
	private GameManager gm; 
	
	/** */
	private JLabel mapName;
	
	/** */
	private LeftMenuPanel016 leftMenu;
	
//	/** */
//	AbstractAI ai;
//	BattlePlayer one; // = new BattlePlayer();
	it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Map arena;
	Chessboard aa;
	/** */
	public PrePlayMatchPanel(final GameManagerMenu gmm)
	{
		super(25,"");
//		System.out.println("!!! start pre mp ");
		monitor = gmm;
		OverallGUILayoutFactory factory = OverallGUILayoutFactory.getInstance();
		IniLoader loader = new IniLoader(new HashMap<String, String>());
		try 
		{
			final String TEXTURE_FOLDER = "settings.maptextures.mainfolder",
					BUTTON_TEXT_SIZE = "pm.button.text.size",
					SPRITE_ROLES = "mapareazone.img.info.roles",
					MAP_NAME_SIZE = "pm.title.mn.text.size",
					MAP_NAME_COLOR = "pm.title.mn.text.color",
					PM_LEFTMENU_WIDTH = "pm.leftmenu.width",
					PM_LEFTMENU_HEIGHT = "pm.leftmenu.height",
					PM_LEFTMENU_BACKSTROKE_COLOR = "pm.leftmenu.background.stroke.color",
					PM_LEFTMENU_STROKE_SIZE = "pm.leftmenu.background.stroke.size",
					PM_BUTTONPANEL_BUTTON_WIDTH = "pm.buttonpanel.button.width",
					PM_BUTTONPANEL_BUTTON_HEIGHT = "pm.buttonpanel.button.height",
					MAPAREAZONE_DIMENSION_WIDTH = "mapareazone.dimension.width",
					MAPAREAZONE_DIMENSION_HEIGHT = "mapareazone.dimension.height";
			loader.load(SETTINGS_FILE);
//			one = gmm.getMainFrame().getGameManager().getClientBattlePlayer(); //TODO: muovere in un metodo "setting" invece che nel costruttore
//			one = gmm.getMainFrame().getGameManager().getMatchManager().
			final Map<String,String> settings = loader.getContents();
			int textSize = Integer.parseInt((String)settings.get(BUTTON_TEXT_SIZE));
//			final ImageProvider imageProvider = new ImageProvider();
//			imageProvider.setTextureFolder(settings.get(TEXTURE_FOLDER));
//			imageProvider.setCharacterRoleFolder(imageProvider.getTextureFolder()+File.separator+"rolesimgs"+File.separator);
			setOpaque(false);

			final SpriteSheetCache spriteCache = new SpriteSheetCache(settings.get(SPRITE_ROLES)+File.separator, new HashMap<AbstractSheetKey, SpriteSheetInterface>());
//			MapManager mapManager = gmm.getMainFrame().getGameManager().getMapManager();
			SimplePlayer client = gmm.getMainFrame().getGameManager().getClientPlayer();
			gm = gmm.getMainFrame().getGameManager();
			try {
//			it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Map arena = null;
				arena = gm.getMapManager().nextMap();
				aa = arena.getArena();
			} catch (InvalidFileException e) {
				e.printStackTrace();
			}
			
			GridBagLayout layout = new GridBagLayout();
			Insets horizonatalSpace = new Insets(0, 5, 0, 15),
					verticalSpace = new Insets(5, 0, 15, 0);
			GridBagConstraints constraints = new GridBagConstraints();
			setLayout(layout);
			mapName = new JLabel();
			mapName.setText(" "+arena.getName()+" ");
			mapName.setFont(factory.getHeaderFont().deriveFont(Float.parseFloat(settings.get(MAP_NAME_SIZE))));
			mapName.setForeground(factory.getParsedColor(settings.get(MAP_NAME_COLOR)));
			mapName.setOpaque(false);
			
			constraints.fill = GridBagConstraints.NONE;
			constraints.anchor = GridBagConstraints.CENTER;
			constraints.gridx = 1;
			constraints.gridy = 0;
			constraints.insets = verticalSpace;
			add(mapName,constraints);
			
			constraints.anchor = GridBagConstraints.EAST;
			constraints.gridx = 0;
			constraints.gridy = 1;
			constraints.insets = horizonatalSpace;
			
////			gm.getMatchManager().init(gm.getClientPlayer(), pl2, one, pl2b, arena, gm.getStatsFactory());
////			SimplePlayer pl2 = new SimplePlayer();
////			pl2.setNickname("PORCELLO");
//////			BattlePlayer pl1 = new BattlePlayer();
////			BattlePlayer pl2b = new BattlePlayer();
////			Character enemy = new Character(1, 1, pl2);
////			enemy.setName("muscolo");
////			enemy.setStats(gm.getStatsFactory().levellingRole("healer", 1));
////			pl2.addCharacter(enemy);
////			pl2b.addCharacter(enemy);
////			enemy.setPosition(4, 1);
////			gm.getMatchManager().init(client, pl2, one, pl2b, arena, gm.getStatsFactory());
//			
////			pl2b.getActions().setAction(StartingPointAction.GUID);
////			pl2b.getActions().addActionInfo(new ActionCoordinateInfo());
			Dimension leftMenuDimension = new Dimension(Integer.parseInt(settings.get(PM_LEFTMENU_WIDTH)), Integer.parseInt(settings.get(PM_LEFTMENU_HEIGHT)));
			LinkedList<GUIGenericPawn> charas = new LinkedList<>();
			
			GUIGenericPawn temp = null;
			for (Character p : client.getCharacters()) {
				
					temp = new GUIGenericPawn();
					temp.setLogicPart(p);
//					temp.setAvatar(imageProvider.getAvatar(p.getStats().getName())); //TODO utilizzare spriteCache
					charas.add(temp);
			}
//			System.out.println("a1");
//			final LeftMenuPanel016 leftMenu = new LeftMenuPanel016(gmm.getMainFrame().getGameManager(),spriteCache, settings, client.getCharacters(), arena);
			leftMenu = new LeftMenuPanel016(gmm.getMainFrame().getGameManager(),spriteCache, settings, client.getCharacters(), arena);
//			System.out.println("a2");

			leftMenu.setPreferredSize(leftMenuDimension);
			leftMenu.setMinimumSize(leftMenuDimension);
			leftMenu.setMaximumSize(leftMenuDimension);
			constraints.gridheight = 2;
			constraints.anchor = GridBagConstraints.LINE_START;
			add(leftMenu,constraints);
			constraints.gridheight = 1;
			constraints.anchor = GridBagConstraints.CENTER;
			leftMenu.setBorder(BorderFactory.createLineBorder(factory.getParsedColor(settings.get(PM_LEFTMENU_BACKSTROKE_COLOR)), Integer.parseInt(settings.get(PM_LEFTMENU_STROKE_SIZE))));
			
			Dimension mapMenuDimension =  new Dimension(Integer.parseInt(settings.get(MAPAREAZONE_DIMENSION_WIDTH)),Integer.parseInt(settings.get(MAPAREAZONE_DIMENSION_HEIGHT))),
					button = new Dimension(Integer.parseInt(settings.get(PM_BUTTONPANEL_BUTTON_WIDTH)), Integer.parseInt(settings.get(PM_BUTTONPANEL_BUTTON_HEIGHT)));
			
			mapMenu = new MapAreaZone016(arena, settings, spriteCache, new LinkedList<GUIGenericPawn>(),mapMenuDimension);

			mapMenu.addML(leftMenu);
			mapMenu.setPreferredSize(mapMenuDimension);
			mapMenu.setMinimumSize(mapMenuDimension);
			
			constraints.fill = GridBagConstraints.NONE;
			constraints.gridx = 1;
			add(mapMenu,constraints);
			
			JPanel buttonsPanel = new JPanel();
			buttonsPanel.setOpaque(false);
			BoxLayout b = new BoxLayout(buttonsPanel, BoxLayout.X_AXIS);
			buttonsPanel.setLayout(b);
			JButton backButton = OverallGUILayoutFactory.getInstance().createButtonUniState(textSize, "Indietro", button.width, button.height, OverallGUILayoutFactory.BUTTON_STATE_ACTIVE);
			backButton.setPreferredSize(new Dimension(button.width, button.height));
			backButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					gmm.showGM(true);
					dispose();
				}
			});
			
			EventManager.getInstance().addListener(this, new StartingPositionEvent());
			EventManager.getInstance().addListener(this, new OutOfMaxCharacterEvent());
			
			buttonsPanel.add(backButton);
			constraints.gridy = 2;
			constraints.insets = verticalSpace;
			final PrePlayMatchPanel ppm = this;
			JButton fightButton = OverallGUILayoutFactory.getInstance().createButtonUniState(textSize, "Combatti", button.width, button.height, OverallGUILayoutFactory.BUTTON_STATE_ACTIVE);
			fightButton.setPreferredSize(new Dimension(button.width, button.height));
			fightButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) 
				{
//					System.out.println("!!!!! --- button --- !!!!");
					//TODO: plz no this fucking random shit
					//TEST
					GameManager gm = gmm.getMainFrame().getGameManager();
				

					if(gm.getMatchManager().checkClient())
					{
						gm.getAi().preStartMatch(arena);
						// era il delay a 110
						gmm.getMainFrame().switchTo(new MatchPanel(110, spriteCache, arena, gm.getMatchManager(), gmm.getMainFrame(), ppm));

						gm.getMatchManager().startMatch(0);
						dispose();
					}
					else
						JOptionPane.showMessageDialog(monitor.getMainFrame(), "Non hai selezionato abbastanza personaggi. Mimino richiesto : "+MatchManager.MINIMUM_CHARACTERS_PER_PLAYER, "Errore", JOptionPane.ERROR_MESSAGE);
//					GraphicEventManager.getInstance().removeListener(this, event)
				}
			});
			buttonsPanel.add(Box.createHorizontalGlue());
			
			buttonsPanel.add(fightButton);
			constraints.fill = GridBagConstraints.HORIZONTAL;
			add(buttonsPanel,constraints);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
//		settingCoso();
	}
	
	@Override
	protected void updateScene() 
	{
		mapMenu.updateGUI();
	}

	@Override
	protected void load(String from) {
		
	}

	@Override
	protected void settingScene() 
	{
		
		
	}
	
	public void settingCoso()
	{
		gm.getMatchManager().init(gm.getClientPlayer(), gm.getAi().getAiPlayer(), gm.getClientBattlePlayer(), gm.getAi().getAiPlayer(), arena);
		leftMenu.someSetting();
	}
	
	
	public void back() 
	{
		super.removeNotify();
		gm.getClientBattlePlayer().disband();
		gm.getMapManager().jumpBack();
//		System.out.println("PRE PLAY MATCH PANEL RIMOSSO DALLA VISTA");
	}
	@Override
	public void notify(GenericEvent event) {

			if(event.getGUID() == StartingPositionEvent.GUID)
			{
				StartingPositionEvent spe = (StartingPositionEvent) event;
				if((spe.getPerformer() == gm.getClientPlayer() || spe.getPerformer() == gm.getMatchManager().getClientPlayer()))
				{
				if(spe.isAdd())
				{
					gm.getClientBattlePlayer().addCharacter(spe.getSubject());
				}
				else
				{
					gm.getClientBattlePlayer().removeCharacter(spe.getSubject());
				}
				}
			}
			else if(event.getGUID() == OutOfMaxCharacterEvent.GUID)
			{
				JOptionPane.showMessageDialog(monitor.getMainFrame(), "Hai troppi personaggi in campo. Massimo possibile: "+MatchManager.MAX_CHARACTERS_PER_PLAYER, "Errore", JOptionPane.ERROR_MESSAGE);
			}else if(event.getGUID() == NotEnoughtCharacterEvent.GUID)
			{
				JOptionPane.showMessageDialog(monitor.getMainFrame(), "Non hai selezionato abbastanza personaggi. Mimino richiesto : "+MatchManager.MINIMUM_CHARACTERS_PER_PLAYER, "Errore", JOptionPane.ERROR_MESSAGE);
			}
		}
	
	/** */
	public void dispose()
	{
		EventManager.getInstance().removeListener(this, new StartingPositionEvent());
		EventManager.getInstance().removeListener(this, new OutOfMaxCharacterEvent());
		
		leftMenu.clear();
		mapMenu.getOrt().dispose();
	}
}
